package ui;

import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem ;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.JFileChooser;
import logica.ProcesadorDeComandos;
import util.mdi.MDIDesktopPane ;


/**
 * Esta clase representa el formulario principal que contiene los componentes
 * mínimos a utilizar en el desarrolo de la aplicación correspondiente al
 * Trabajo Práctico Nº 1 de Diseño e Implementación de Estructuras de Datos.
 * Universidad Tecnológica Nacional - Facultad Regional Santa Fe.
 *
 * @author Cátedra DIED 2007.
 */
public class ScriptorPpal extends JFrame implements	InternalFrameListener, ActionListener {

	private static final long serialVersionUID = -2811861569233422674L;
	static final int desktopWidth = 640;
	static final int desktopHeight = 480;
	static final int panelHeight = 90;

	private MDIDesktopPane panelPrincipal;
	private JScrollPane scrollPane;
	private Vector documentosAbiertos;
	private JMenu menuArchivo;
	private JMenuItem menuItemNuevo;
    private JMenu menuDiccionario;
    private JMenuItem seleccionarDiccionario;
    private JMenuItem itemAgregarPalabra;
    private JMenuItem itemModificarPalabra;
    private JMenuItem itemBorrarPalabra;
    private JMenu menuTags;
    private JMenuItem seleccionarTags;
    private JMenuItem itemAgregarTags;
    private JMenuItem itemModificarTags;
    private JMenuItem itemBorrarTags;
	private JMenuBar barraDeMenus;
	private PanelDeComandos panelDeComandos;
	private ProcesadorDeComandos procesadorDeComandos;

	int idSeleccionado = -1;


	/**
	 * Constructor del Frame.
	 * @throws HeadlessException
	 */
	public ScriptorPpal() throws HeadlessException {

		super();
		this.inicializarVentana();
        System.out.println("\n------------------------------------------------");
        System.out.println("\tBienvenidos a Procesador de Palabras 0.02");
        System.out.println("Autores: Kaufmann - Heizenreder - Perales");
        System.out.println("Site del proyecto: http://code.google.com/p/procesadorpalabras/");
	}


	/**
	 * Método que inicializa los parámetros de la ventana.
	 */
	private void inicializarVentana() {

		this.setTitle("Scriptor Version 0.02 ");
		JFrame.setDefaultLookAndFeelDecorated(true);
		ImageIcon logo = createImageIcon("/img/scriptor.gif","Logo de la aplicaciÃ³n");

		procesadorDeComandos=new ProcesadorDeComandos(this);

		this.setIconImage(logo.getImage()) ;

		//Setear la GUI.
		scrollPane = new JScrollPane();
		panelPrincipal = new MDIDesktopPane();
		panelPrincipal.putClientProperty("JDesktopPane.dragMode",
							  "outline");
		//Como usamos pack, no es suficiente llamar a setSize.
		//Debemos setear el tamaÃ±o preferido del panel principal.
		panelPrincipal.setPreferredSize(new Dimension(desktopWidth, desktopHeight));

		scrollPane.getViewport().add(panelPrincipal);
        //Menu archivo
		menuArchivo = new JMenu("Archivo");
		menuItemNuevo = new JMenuItem("Nuevo");
		menuItemNuevo.addActionListener(this);
		menuArchivo.add(menuItemNuevo);
        //Menu Diccionario
        menuDiccionario = new JMenu("Diccionario");
        seleccionarDiccionario = new JMenuItem("Seleccionar...");
        seleccionarDiccionario.addActionListener(this);
        itemAgregarPalabra = new JMenuItem("Agregar palabra");
        itemAgregarPalabra.addActionListener(this);
        itemBorrarPalabra = new JMenuItem("Borrar palabra");
        itemBorrarPalabra.addActionListener(this);
        itemModificarPalabra = new JMenuItem("Modificar palabra");
        itemModificarPalabra.addActionListener(this);
        menuDiccionario.add(seleccionarDiccionario);
        menuDiccionario.addSeparator();
        menuDiccionario.add(itemAgregarPalabra);
        menuDiccionario.add(itemBorrarPalabra);
        menuDiccionario.add(itemModificarPalabra);
        //Menu tags
        menuTags = new JMenu("Tags");
        seleccionarTags = new JMenuItem("Seleccionar...");
        seleccionarTags.addActionListener(this);
        itemAgregarTags = new JMenuItem("Agregar tags");
        itemAgregarTags.addActionListener(this);
        itemBorrarTags = new JMenuItem("Borrar tags");
        itemBorrarTags.addActionListener(this);
        itemModificarTags = new JMenuItem("Modificar tags");
        itemModificarTags.addActionListener(this);
        menuTags.add(seleccionarTags);
        menuTags.addSeparator();
        menuTags.add(itemAgregarTags);
        menuTags.add(itemBorrarTags);
        menuTags.add(itemModificarTags);
        //Armamos la barra de menu
		barraDeMenus = new JMenuBar();
        barraDeMenus.add(menuArchivo);
        barraDeMenus.add(menuDiccionario);
        barraDeMenus.add(menuTags);

		this.setJMenuBar(barraDeMenus);
		panelDeComandos = new PanelDeComandos(this);

		this.getContentPane().add("North",scrollPane);

		this.getContentPane().add("South",panelDeComandos);
		panelDeComandos.mensajeDeInformacion("Bienvenido a la version 0.02 de Scriptor");
		documentosAbiertos = new Vector();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/**
	 *
	 */
    private static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);

		ScriptorPpal ventana = new ScriptorPpal();
		ventana.pack();
		ventana.setVisible(true);
    }


    public static void main(String[] args) {
        //Calendarizar un trabajo para el hilo de envío de eventos:
        //creación y muestra de la ventana principal.
        /*
        try {
			UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}*/
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }


	/**
	 * Evento que se dispara cuando se selecciona una ventana.
	 */
	public void internalFrameActivated(InternalFrameEvent arg0)
	{
		if (!(arg0.getInternalFrame() instanceof DocumentoDeTexto)) return;
		this.setIdSeleccionado(((DocumentoDeTexto)arg0.getInternalFrame()).getId());
	}

	public void internalFrameDeactivated(InternalFrameEvent arg0)
	{
	}

	/**
	 * Manejo de una acción, que puede ser:
	 * 	- Click sobre un ítem de menú.
	 *
	 */
	public void actionPerformed(ActionEvent arg0){
        DocumentoDeTexto documentoActual = getDocumentoActual();
        if(arg0.getSource().equals(this.menuItemNuevo)){
            this.cargarTexto(new DocumentoDeTexto("Documento nuevo",this));
        }
        else if(documentoActual == null){
            mostrarAdvertencia("Para llevar a cabo la accion que desea ejecutar\ndebe tener un documento abierto.");
        }
        else{
            if(arg0.getSource().equals(this.seleccionarDiccionario)){
                System.out.println("Seleccionar Diccionario de Palabras");
                String path = seleccionarDiccionario();
                // cargo el diccionario para el documento actual
                System.out.println("Cargando diccionario de palabras ...");
                documentoActual.cargarDiccionario(path, true);
            }
            else if(arg0.getSource().equals(this.seleccionarTags)){
                System.out.println("Seleccionar Diccionario de Tags");
                String path = seleccionarDiccionario();
                // cargo el diccionario de tags al documento actual
                System.out.println("Cargando diccionario de tags ...");
                documentoActual.cargarDiccionario(path, false);
            }
            else if(documentoActual.diccionarioCargado()){
                if(arg0.getSource().equals(this.itemAgregarPalabra)){
                    String palabra = this.agregarCadena("Palabra");
                    if (palabra!= "" && palabra != null){
                        System.out.println("Palabra agregada: " + palabra);
                        documentoActual.agregarPalabra(palabra);
                   }
                }
                else if(arg0.getSource().equals(this.itemModificarPalabra)){
                    System.out.println("Modificar Palabra");
                    String[] palabra = this.modificarCadena("Palabra");
                    if(palabra[0] != "" && palabra[0] != null){
                        String palabraVieja = palabra[0];
                        String palabraNueva = palabra[1];
                        documentoActual.modificarPalabra(palabraVieja, palabraNueva);
                    }
                }
                else if(arg0.getSource().equals(this.itemBorrarPalabra)){
                    String palabra = this.borrarCadena("Palabra");
                    if (palabra != "" && palabra != null){
                        System.out.println("Palabra borrada: " + palabra);
                        documentoActual.borrarPalabra(palabra);
                    }
                }
                else if(arg0.getSource().equals(this.itemAgregarTags)){
                    String palabra = this.agregarCadena("Tags");
                    if (palabra!= "" && palabra != null){
                        System.out.println("Tags agregado: " + palabra);
                        //documentoActual.agregarPalabra(palabra);
                    }
                }
                else if(arg0.getSource().equals(this.itemBorrarTags)){
                   String palabra = this.borrarCadena("Tags");
                   if (palabra != "" && palabra != null){
                        System.out.println("Tags borrada: " + palabra);
                        //documentoActual.borrarPalabra(palabra);
                    }
                 }
                else if(arg0.getSource().equals(this.itemModificarTags)){
                    System.out.println("Modificar Tags");
                    String[] palabra = this.modificarCadena("Tags");
                    if(palabra[0] != "" && palabra[0] != null){
//                         String palabraVieja = palabra[0];
//                         String palabraNueva = palabra[1];
                        //documentoActual.modificarPalabra(palabraVieja, palabraNueva);
                    }

                }
            }
            else{
                mostrarAdvertencia("Debe cargar un diccionario antes de ejecutar esta accion");
            }
        }
	}

    public void mostrarAdvertencia(String mensaje){
    JOptionPane.showMessageDialog(this,
            mensaje,
            "Error",
            JOptionPane.ERROR_MESSAGE);
    }
    
    /**
     * Desplegará un JFileChoocer para asi buscar el diccionario que el usuario
     * quiera utilizar para la funcion de autocompletado.
     * @param none
     * @return path donde se encuentra el archivo
     */
    public String seleccionarDiccionario(){
        if(getDocumentoActual() == null){
            System.out.println("No tiene abierto ningÃºn documento");
            JOptionPane.showMessageDialog(this,
                    "Para agregar un diccionario debe tener un documento abierto.",
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
            return "";
        }
        else{
            String cadena = "";
            JFileChooser chooser = new JFileChooser();
            FiltreSimple filter = new FiltreSimple("Achivos de texto","txt");
            chooser.addChoosableFileFilter(filter);
            int returnVal = chooser.showOpenDialog(this);
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                cadena = chooser.getSelectedFile().getPath();
                System.out.println("Eligio el diccionario: " + cadena);
            }
            return cadena;
        }
     }
    /**
     * Generará el JDialog agragar cadena (tanto palabra comoo tags) y devuelve
     * la cadena introducida.
     * @param opcion Puede ser palabra o tags
     * @return cadena es la que se agragarÃ¡ al diccionario actual.
     */
    public String agregarCadena(String opcion){
        JOptionPane pane = new JOptionPane();
        String cadena = JOptionPane.showInputDialog(pane,
                opcion + ": ",
                "Agregar " + opcion,
                3);
        System.out.println(cadena);
        if (this.datosValidos(pane, cadena))
            return cadena;
        else
            return "";
            //Esto no deberia ser asi, pero no encuentro la forma de que pane se
            //ejecute hasta que el usuario tipe bien. Capaz esta bien que sea
            //asi y lo que quiero hacer es una boludez.
    }
    /**
     * Generará el JDialog borrar palabra y devuelve la palabra introducida.
     * @param none
     * @return cadena es la que borraremos del diccionario.
     */
    public String borrarCadena(String opcion){
        JOptionPane pane = new JOptionPane();
        String cadena = JOptionPane.showInputDialog(pane,
                opcion +": ",
                "Borrar " + opcion +"del Diccionario",
                3);
        if (this.datosValidos(pane, cadena))
            return cadena;
        else
            return "";
    }
    /**
     * Generará el dialogo para la modificacion de una cadena (tanto palabra
     * como tags en el diccionario que le corresponda.
     * @param cadena Puede ser palabra o tags
     * @return palabras es un arreglo de dos posiciones, la primera es la
     * palabra a modificar, la segunda es la modificacion.
     */
    public String[] modificarCadena(String opcion){
        String[] palabras = new String[2];
        String[] texto = new String[2];
        JOptionPane pane = new JOptionPane();
        texto[0] = opcion + " a modificar:";
        texto[1] = "Modificar por la siguiente " + opcion;

        for(int i=0;i<2;i++){
            palabras[i] = JOptionPane.showInputDialog(pane,
                texto[i],
                "Modificar Palabra",
                3);
        }
        return palabras;
    }
    /**
     * Permite validar el textfield de agregar cadena y borrar cadena.
     * @param padre es el JOptionPane que lo llama
     * @param dato es lo que el usuario ingresa
     * @return true or false
     */
    public boolean datosValidos(JOptionPane padre, String dato){
        if (dato == "uninitializedValue"){
            JOptionPane.showMessageDialog(padre,
                    "El campo no puede ser vacio.",
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
            return false;
        }
        return true;
    }

	/**
	 * Ubica el documento dentro del panel principal de la aplicaciÃ³n.
	 * @param documento 	Documento a ubicar.
	 */
	private void ubicarDocumento(DocumentoDeTexto documento) {
		documento.setLocation(12*documento.getId(),9*documento.getId());
	}
	/**
	 * Accion de cargar un documento.
	 * @param documentoNuevo 	Documento a cargar.
	 */
	private void cargarTexto(DocumentoDeTexto documentoNuevo) {
		 this.documentosAbiertos.addElement(documentoNuevo);
		 documentoNuevo.setId(documentosAbiertos.size()-1);
		 ubicarDocumento(documentoNuevo);
		 panelPrincipal.add(documentoNuevo);
	      try {
		        documentoNuevo.setSelected(true);
	        } catch (java.beans.PropertyVetoException e) {}
	     this.idSeleccionado = documentoNuevo.getId();
		 documentoNuevo.setVisible(true);
	}
	/**
	 *
	 * @param path
	 * @param description
	 * @return ImageIcon
	 */
	protected ImageIcon createImageIcon(String path, String description) {
		java.net.URL imgURL = getClass().getResource(path);
		if (imgURL != null)
		{
			return new ImageIcon(imgURL, description);
		}
		else {
			System.err.println("Archivo no encontrado: " + path);
			return null;
		}
	}

    /**
     * Agrega el mensaje la panel de comandos
     * @param msj
     */
    public void msjResultado(String msj){
        this.panelDeComandos.msjResultado(msj);
    }
    /**
     * Limpia el panel de comandos
     * @param none
     */
    public void limpiar(){
       this.panelDeComandos.limpiar();
    }
	/**
	 *
	 * @param mensaje
	 */
	public void mensajeDeInformacion(String mensaje) {
		this.panelDeComandos.mensajeDeInformacion(mensaje);
	}
	/**
	 *
	 * @param mensaje
	 */
	public void mensajeDeError(String mensaje){
		this.panelDeComandos.mensajeDeError(mensaje);
	}
	/**
	 *
	 * @return Dimension
	 */
	public Dimension getTamActual() {
		return (new Dimension(640,480));
	}
	/**
	 *
	 * @param comando
	 */
	public void recibirComando(String comando) {
		this.procesadorDeComandos.procesarComando(comando);
	}
	/**
	 *
	 * @return DocumentoDeTexto
	 */
	public DocumentoDeTexto getDocumentoActual() {
		if(this.idSeleccionado<0)
			return null;
		return ((DocumentoDeTexto)this.documentosAbiertos.elementAt(this.idSeleccionado));
    }
    public int getIdSeleccionado() {
		return idSeleccionado;
	}

    public PanelDeComandos getPanelDeComando(){
        return this.panelDeComandos;
    }

    public ProcesadorDeComandos getProcesadorDeComandos(){
        return this.procesadorDeComandos;
    }

	public void setIdSeleccionado(int idSeleccionado) {
		this.idSeleccionado = idSeleccionado;
	}
	public void internalFrameOpened(InternalFrameEvent arg0){
	}

	public void internalFrameClosing(InternalFrameEvent arg0){

	}

	public void internalFrameClosed(InternalFrameEvent arg0){

	}

	public void internalFrameIconified(InternalFrameEvent arg0){

	}

	public void internalFrameDeiconified(InternalFrameEvent arg0){
	}
}
